﻿using System;
using System.IO;

namespace Tatibah
{
    /// <summary>
    /// This class represents an Image (picture)
    /// </summary>
    public class Image : iParagraphAppend, iCellAppend
    {
        /// <summary>
        /// Set internally if there were any errors processing the Image
        /// </summary>
        public bool Errors = false;
        /// <summary>
        /// Set internally if there were any errors processing the Image
        /// </summary>
        public string ErrorMessage = "";

        /// <summary>
        /// Border colour as hex string RRGGBB
        /// </summary>
        public  string BorderColour = "";
        private double borderWidth = 0.5; // 0.5 points
        private long outputWidth = 0;
        private long outputHeight = 0;
       
        // Don't want the users to set these
        private string imageId = "";
        private long width = 0;
        private long height = 0;
        private double widthScalingPercent = 100.0;
        private double heightScalingPercent = 100.0;
        private string fileName = "";
        private byte[] image = null;
      
        /// <summary>
        /// Create an Image from a filename
        /// </summary>
        /// <param name="FileName"></param>
        public Image(string FileName)
        {
            FileInfo fi = new FileInfo(FileName);
            if (fi.Exists)
                fileName = FileName;
            else
            {
                Errors = true;
                ErrorMessage = "File Not found at " + FileName;
            }
        }

        /// <summary>
        /// Create an Image from a byte array
        /// </summary>
        /// <param name="ThisImage"></param>
        public Image(byte[] ThisImage)
        {
            image = ThisImage;
        }
       
        
        #region P R O P E R T I E S
        /// <summary>
        /// The Internal Id of the Image. This is set once the Image has been saved to the Document
        /// </summary>
        public string ImageId
        {
            get { return imageId; }
        }

        /// <summary>
        /// Units are EMUs. This is set once the Image has been saved to the Document
        /// </summary>
        public long Width
        {
            get { return width; }
        }

        /// <summary>
        /// Units are EMUs. This is set once the Image has been saved to the Document
        /// </summary>
        public long Height
        {
            get { return height; }
        }

        /// <summary>
        /// Scaling the image in relation to its original size. A value 0f 50 will be an image reduced by 50%
        /// </summary>
        public double Scaling
        {
            
            set
            {
                widthScalingPercent = value;
                heightScalingPercent = value;
                outputHeight = (long)  Math.Round(height * value / 100.0, 0);
                outputWidth = (long) Math.Round(width * value / 100.0, 0);
            }
        }

        /// <summary>
        /// Scaling the image in relation to its original size. A value 0f 50 will be an image with a width reduced by 50%
        /// </summary>
        public double WidthScaling
        {
            get { return widthScalingPercent; }
            set
            {
                if (value > 0)
                {
                    widthScalingPercent = value;
                    outputWidth = (long)Math.Round(width * value / 100.0, 0);
                }
            }
        }

        /// <summary>
        /// Scaling the image in relation to its original size. A value 0f 50 will be an image with a width reduced by 50%
        /// </summary>
        public double HeightScaling
        {
            get { return heightScalingPercent; }
            set
            {
                if (value > 0)
                {
                    heightScalingPercent = value;
                    outputHeight = (long)Math.Round(height * value / 100.0, 0);
                }
            }
        }

        /// <summary>
        /// Get the filename from which the image was created, empty if created from a byte array
        /// </summary>
        public string FileName
        {
            get { return fileName; }
        }

        /// <summary>
        /// Get the byte array from which the iamge was created, null if the image was created from a filename
        /// </summary>
        public byte[] ImageArray
        {
            get { return image; }
        }

        /// <summary>
        /// The height of the displayed image in EMUs
        /// </summary>
        public long OutputHeight
        {
            get { return outputHeight; }
        }

        /// <summary>
        /// The width of the displayed image in EMUs
        /// </summary>
        public long OutputWidth
        {
            get { return outputWidth; }
        }

        /// <summary>
        /// Border width are in quarter points eg 10.75
        /// </summary>
        public double BorderWidth
        {
            get { return borderWidth; }
            set
            {
                // Font sizes can either be whole numbers or whole numbers plus a half
                if (value * 4 == Math.Floor(value * 4))
                    borderWidth = value;
                else
                    throw new Exception("Border size must be either a whole number or a whole number plus quarters e.g 8, or 11.75");

            }
        }

        #endregion P R O P E R T I E S

      /// <summary>
      /// Function for Internal use only
      /// </summary>
        public void ReservedH(long NewHeight, long NewWidth)
        {
            height = NewHeight;
            outputHeight = (long)Math.Round(NewHeight * heightScalingPercent / 100.0);
            width = NewWidth;
            outputWidth = (long)Math.Round(NewWidth * widthScalingPercent / 100.0);
        }

        /// <summary>
        /// Function for Internal use only
        /// </summary>
        public void ReservedI(string Id)
        {
            if (string.IsNullOrEmpty(imageId))
                imageId = Id;
            else
                throw new Exception("Image Id can only be set once");
        }

    }
}
